package domain;

import Technical.DatabaseHandler;
import gui2.OthelloUI;
import gui2.outputInterface;

/*
 * This class will handle everything with the games proceedings.
 */
/*
 * IMPLEMENTATION STATUS - The main game loop. - Check if game over. - And lots
 * more...
 */
public class GameManager implements Runnable
{

    private OthelloUI othelloUI;
    private Player player1;
    private Player player2;
    private int p1type;
    private int p2type;
    private int p1AI;
    private int p2AI;
    private boolean gameOver = false;
    private UserInputQueue queue;
    private int debugMode;
    private int trainingMode;
    private outputInterface outInterface;
    private int[][] ggrid;

    public GameManager(OthelloUI othelloUI, int p1type, int p2type, int p1AI, int p2AI, UserInputQueue queue, int debugMode, outputInterface outInterface, int[][] grid, int trainingMode)
    {
        this.othelloUI = othelloUI;
        this.p1type = p1type;
        this.p2type = p2type;
        this.p1AI = p1AI;
        this.p2AI = p2AI;
        this.queue = queue;
        this.debugMode = debugMode;
        this.trainingMode = trainingMode;
        this.outInterface = outInterface;
        this.ggrid = grid;
    }

    @Override
    public void run()
    {
        //DatabaseHandler.getInstance().tunaktuankDB();
        System.out.println("run is running lol");
        Move move = new Move(2, 3);
        GameGrid grid = new GameGrid();
        if (ggrid != null) {
            GameGrid clone = new GameGrid();
            // Convert int[][] to gamegrid
            Square[][] newGrid = new Square[8][8];

            for (int i = 0; i < 8; i++) {
                for (int j = 0; j < 8; j++) {
                    newGrid[i][j] = new Square(ggrid[i][j]);
                    clone.GameGrid[i][j].setOwner(ggrid[i][j]);
                }
            }
            clone.printGrid();
            grid = copyGrid(clone);
        }
        //grid.GameGrid = newGrid;

        //grid.GameGrid = copyGrid();
        //

        othelloUI.UpdateUIBoard(grid.GameGrid);

        if (p1type == 1) {
            System.out.println("human 1");
            player1 = new Human("1", 1, queue);
        } else {
            System.out.println("Computer 1");
            player1 = new Computer("1", 1, p1AI, outInterface, debugMode);
        }
        if (p2type == 1) {
            System.out.println("human 2");
            player2 = new Human("2", 2, queue);
        } else {
            System.out.println("computer 2");
            player2 = new Computer("2", 2, p2AI, outInterface, debugMode);
        }

        while (gameOver == false) {

            // Player 1 turn.
                //othelloUI.PrintToOutputScreen("waiting for move from player 1");
            boolean player1Done = false;
            while (player1Done != true && gameOver == false) {
                //System.out.println("game over: "+ gameOver+" player1Done: "+player1Done);
                // Gets a move from the queue.
                move = player1.makeMove(grid);
                if (move != null && grid.isLegalMove(1, move.getX(), move.getY())) {
                    grid.makeMove(1, move.getX(), move.getY());
                    //  othelloUI.PrintToOutputScreen("made move on " + move.getX() + "-" + move.getY());
                    othelloUI.UpdateUIBoard(grid.GameGrid);
                    player1Done = true;
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException ex) {
                        System.out.println("Error while trying to sleep the thread.");
                    }
                    //System.out.println("testing game over");
                    gameOver = grid.isTerminalState();
                } else {
                    if (grid.isTerminalState(1)) {
                        //System.out.println("player one folds!");
                        player1Done = true;
                    }
                    gameOver = grid.isTerminalState();
                    //System.out.println("not a valid move");
                        //othelloUI.PrintToOutputScreen("Not a valid move. Try again.");
                }
            }

            // Player 2 turn.
                //othelloUI.PrintToOutputScreen("waiting for move from player 2");
            boolean player2Done = false;
            while (player2Done != true && gameOver == false) {
                // Gets a move from the queue.
                move = player2.makeMove(grid);
                //System.out.println("Player two turn");
                // Checks to see if the move is legal.
                if (move != null && grid.isLegalMove(2, move.getX(), move.getY())) {
                    // listener.repaintGameBoard(gameGrid);
                    grid.makeMove(2, move.getX(), move.getY());
                    //grid.printGrid();
                        //othelloUI.PrintToOutputScreen("made move on " + move.getX() + "-" + move.getY());
                    othelloUI.UpdateUIBoard(grid.GameGrid);
                    player2Done = true;
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException ex) {
                        System.out.println("Error while trying to sleep the thread.");
                    }
                    // Checks if the latest move was a winning move.
                    gameOver = grid.isTerminalState();
                } else {
                    if (grid.isTerminalState(2)) {
                        //System.out.println("player two folds!");
                        player2Done = true;
                    }
                    gameOver = grid.isTerminalState();
                    //System.out.println("not a valid move 2");
                        //othelloUI.PrintToOutputScreen("Not a valid move. Try again.");
                }

            }
        }

        if (p1type == 2) {
            player1.evaluateGame(grid);
        }
        if (p2type == 2) {
            player2.evaluateGame(grid);
        }

        System.out.println("game over");
        System.out.println("a winner is " + grid.GetWinner());
        System.out.println("score: " + grid.getCount(grid.GetWinner()));
        
        if(trainingMode == 1){
            othelloUI.rerun();
        }
    }

    private GameGrid copyGrid(GameGrid gridOne)
    {
        GameGrid gridCopy = new GameGrid();

        for (int y = 0; y < 8; y++) {
            for (int x = 0; x < 8; x++) {
                if (gridOne.GameGrid[x][y].getOwner() == 1) {
                    gridCopy.GameGrid[x][y].setOwner(1);
                } else if (gridOne.GameGrid[x][y].getOwner() == 2) {
                    gridCopy.GameGrid[x][y].setOwner(2);
                } else if (gridOne.GameGrid[x][y].getOwner() == 0) {
                    gridCopy.GameGrid[x][y].setOwner(0);
                }

            }

        }
        return gridCopy;
    }
}
